﻿using HelloWPF.Study.WPFControls.Model;
using HelloWPF.Study.WPFControls.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace HelloWPF.Study.WPFControls.TreeView
{
    /// <summary>
    /// TreeViewDynamic.xaml 的交互逻辑
    /// </summary>
    public partial class TreeViewDynamic : Window
    {
        private Point _lastMouseDown;
        private MenuItemBase _targetItem;
        private MenuItemBase _draggedItem;
        TreeViewDynamicViewModel viewModel;
        public TreeViewDynamic()
        {
            InitializeComponent();
            viewModel = new TreeViewDynamicViewModel();
            this.DataContext = viewModel;
        }
       
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            #region 代码方式添加节点
            //{
            //    //根节点1-Project
            //    TreeViewItem rootNode1 = new TreeViewItem();
            //    rootNode1.Header = "Project";
            //    tvList.Items.Add(rootNode1);

            //    //根节点1下添加1个子节点
            //    TreeViewItem rootNode1ChildNode1 = new TreeViewItem();
            //    rootNode1ChildNode1.Header = "PAPilot.tp";
            //    rootNode1.Items.Add(rootNode1ChildNode1);

            //    //1个子节点3个子节点
            //    TreeViewItem setupsNode = new TreeViewItem();
            //    setupsNode.Header = "setups";
            //    rootNode1ChildNode1.Items.Add(setupsNode);

            //    TreeViewItem flowsNode = new TreeViewItem();
            //    flowsNode.Header = "flows";
            //    rootNode1ChildNode1.Items.Add(flowsNode);

            //    TreeViewItem limitsNode = new TreeViewItem();
            //    limitsNode.Header = "limits";
            //    rootNode1ChildNode1.Items.Add(limitsNode);

            //    //根节点2-TestMethods
            //    TreeViewItem rootNode2 = new TreeViewItem();
            //    rootNode2.Header = "TestMethods";
            //    tvList.Items.Add(rootNode2);

            //    //根节点3-InstrSupport
            //    TreeViewItem rootNode3 = new TreeViewItem();
            //    rootNode3.Header = "InstrSupport";
            //    tvList.Items.Add(rootNode3);
            //}
            #endregion
        }

        #region 拖拽
        /// <summary>
        /// 当鼠标指针在指定的元素中移动时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                //if (e.LeftButton == MouseButtonState.Pressed)
                //{
                //    Point currentPosition = e.GetPosition(tvList);//
                //    if ((Math.Abs(currentPosition.X - _lastMouseDown.X) > 10.0) ||
                //        (Math.Abs(currentPosition.Y - _lastMouseDown.Y) > 10.0))
                //    {
                //        _draggedItem = (MenuItemBase)tvList.SelectedItem;//拖拽项
                //        DragDropEffects finalDropEffect = DragDrop.DoDragDrop(tvList, tvList.SelectedValue,
                //            DragDropEffects.Move);
                //        //Checking target is not null and item is dragging(moving)
                //        //移动 & 目标 & 源不能为空
                //        if (finalDropEffect == DragDropEffects.Move && _targetItem != null && _draggedItem != null)
                //        {
                //            if (_draggedItem.Id != _targetItem.Id)
                //            {
                //                MoveMenuItem(_draggedItem, _targetItem);
                //                _targetItem = null;
                //                _draggedItem = null;
                //            }
                //        }
                //    }
                //}
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void treeView_DragOver(object sender, DragEventArgs e)
        {
            try
            {
                //Point currentPosition = e.GetPosition(tvList);
                //if ((Math.Abs(currentPosition.X - _lastMouseDown.X) > 10.0) ||
                //    (Math.Abs(currentPosition.Y - _lastMouseDown.Y) > 10.0))
                //{
                //    // Verify that this is a valid drop and then store the drop target
                //    TreeViewItem item = GetNearestContainer(e.OriginalSource as UIElement);
                //    //if (CheckDropTarget(draggedItem, item))
                //    //{
                //    //    e.Effects = DragDropEffects.Move;
                //    //}
                //    //else
                //    //{
                //    //    e.Effects = DragDropEffects.None;
                //    //}
                //}
                e.Handled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 拖拽松手时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView_Drop(object sender, DragEventArgs e)
        {
            try
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string msg = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
                    e.Handled = true;

                    //e.Effects = DragDropEffects.Move;
                    //Verify that this is a valid drop and then store the drop target
                    //TreeViewItem targetItem = GetNearestContainer(e.OriginalSource as UIElement);
                    ////被拖拽项不为空且目标项不为空
                    //if (targetItem != null && _draggedItem != null)
                    //{
                    //    _targetItem = targetItem.Header as MenuItemBase;
                    //    e.Effects = DragDropEffects.Move;
                    //}
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 移动Menu item
        /// </summary>
        /// <param name="_sourceItem"></param>
        /// <param name="_targetItem"></param>
        private void MoveMenuItem(MenuItemBase sourceItem, MenuItemBase targetItem)
        {
            //Asking user wether he want to drop the dragged TreeViewItem here or not
            if (MessageBox.Show("Would you like to drop " + sourceItem.Name + " into " + targetItem.Name + "", "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                try
                {
                    //1.从被拖拽项的父元素中移除掉该被拖拽项
                    RemoveSourceItem(sourceItem, targetItem, viewModel.MenuList);

                    //2.给新目标添加新元素
                    ToTargetItemAddItem(sourceItem, targetItem, viewModel.MenuList);

                    //3.改变源Item的父Id
                    sourceItem.ParentId = targetItem.Id;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        /// <summary>
        /// 给新目标添加新元素
        /// </summary>
        /// <param name="sourceItem"></param>
        /// <param name="targetItem"></param>
        private void ToTargetItemAddItem(MenuItemBase sourceItem, MenuItemBase targetItem, ObservableCollection<MenuItemBase> menuList)
        {
            if (menuList.Count == 0)
            {
                return;
            }
            foreach (var menu in menuList)
            {
                if (menu.Id == targetItem.Id)
                {
                    menu.SubMenuItems.Add(sourceItem);
                    return;
                }
                else
                {
                    ToTargetItemAddItem(sourceItem, targetItem, menu.SubMenuItems);
                }
            }
        }

        /// <summary>
        /// 从被拖拽项的父元素中移除掉该被拖拽项
        /// </summary>
        /// <param name="sourceItem"></param>
        /// <param name="targetItem"></param>
        private void RemoveSourceItem(MenuItemBase sourceItem, MenuItemBase targetItem, ObservableCollection<MenuItemBase> menuList)
        {
            if(sourceItem.ParentId ==0)//根节点
            {
                var rootMenu = menuList.FirstOrDefault(menu=>menu.Id == sourceItem.Id);
                menuList.Remove(rootMenu);
                return;
            }

            if (menuList.Count == 0)
            {
                return;
            }
            foreach (var menu in menuList)
            {
                if (menu.Id == sourceItem.ParentId)
                {
                    menu.SubMenuItems.Remove(sourceItem);
                    return;
                }
                else
                {
                    RemoveSourceItem(sourceItem, targetItem, menu.SubMenuItems);
                }
            }
        }

        private TreeViewItem GetNearestContainer(UIElement element)
        {
            // Walk up the element tree to the nearest tree view item.
            TreeViewItem container = element as TreeViewItem;
            while ((container == null) && (element != null))
            {
                element = VisualTreeHelper.GetParent(element) as UIElement;
                container = element as TreeViewItem;
            }
            return container;
        }

        /// <summary>
        /// 拖拽进入treeview范围
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TvList_DragEnter(object sender, DragEventArgs e)
        {

        }
        #endregion

        /// <summary>
        /// 节点选中响应事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TvList_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            var val = e.NewValue as MenuItemBase;
            if (val != null)
            {
                System.Windows.Controls.ContextMenu contextMenu = new System.Windows.Controls.ContextMenu();
                System.Windows.Controls.MenuItem menuItem1 = new System.Windows.Controls.MenuItem();
                menuItem1.Header = "Insert after";
                menuItem1.Click += AddItemToBefore_Click;
                contextMenu.Items.Add(menuItem1);
                System.Windows.Controls.MenuItem menuItem2 = new System.Windows.Controls.MenuItem();
                menuItem2.Header = "Insert before";
                menuItem2.Click += AddItemToBefore_Click;
                contextMenu.Items.Add(menuItem2);
                System.Windows.Controls.MenuItem menuItem3 = new System.Windows.Controls.MenuItem();
                menuItem3.Header = "添加到里面";
                menuItem3.Click += AddItemToInterior_Click;
                contextMenu.Items.Add(menuItem3);
                //tvList.ContextMenu = contextMenu;
            }
        }

        #region 添加到里面 & 添加到前面 & 添加到后面
        /// <summary>
        /// 添加到里面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddItemToInterior_Click(object sender, RoutedEventArgs e)
        {

        }

        /// <summary>
        /// 添加到前面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddItemToBefore_Click(object sender, RoutedEventArgs e)
        {

        }

        /// <summary>
        /// 添加到后面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddItemToAfter_Click(object sender, RoutedEventArgs e)
        {

        }
        #endregion
    }
}
